#include <Game.h>

Game::Game(EchoParser* song)
{
	//
	mPlayer = NULL;
	mEnemies = new vector<NonPlayerCharacter*>();
	mBaseMap = NULL;
	mParsedSong = song;
	mCommands = NULL;
	mMusicTimestamp = -1;
	
	/*
	Initialize achievement level to -1,
	since 0..10 is reserved for indicating
	achievement level.
	*/
	mAchievementLevel = -1;
	mScore = 0;
	//Initialize music point list to null; should be initialized by ogre
	mMusicPoints = NULL;
	mPointBenchmarks = NULL;//
	mLastPassedMusicPoint = -1;
	mLastPassedMusicPoint2 = -1;
	
	
}

Game::~Game()
{
	//
	delete mEnemies;
}

void Game::setBaseMap(BaseMap* m)
{
	assert(m);
	mBaseMap = m;
}

int Game::getAchievementLevel()
{
	return mAchievementLevel;
}

int Game::getLastPassedMusicPoint()
{
	return mLastPassedMusicPoint;
}

int Game::getScore()
{
	return mScore;
}

EchoParser* Game::getSong()
{
	return mParsedSong;
}

vector<NonPlayerCharacter*>* Game::getEnemies()
{
	return mEnemies;
}

vector<Command_t*>* Game::getCommands()
{
	return mCommands;
}

void Game::update(float timeSinceStarted)
{
	mTimeSinceStarted = timeSinceStarted;
	assert(mPlayer);
	//Update all the characters
	mPlayer->update(timeSinceStarted);
	for(int i = 0; i < mEnemies->size(); i++)
	{
		NonPlayerCharacter* npc = (*mEnemies)[i];
		npc->update(timeSinceStarted);
	}
	
	if(mPlayer->isDead())
	{
		mIsOver = true;
	}
}

void Game::addScore(int s)
{
	mScore += s;
}

void Game::setLastPassedMusicPoint(int p)
{
	int temp = mLastPassedMusicPoint;
	mLastPassedMusicPoint = p;
	if( p != temp)
	{
		mLastPassedMusicPoint2 = temp;
	}
}

void Game::setMusicTimestamp(unsigned int timestamp)
{
	//Update class with latest audio timestamp
	mMusicTimestamp = timestamp;
	
	//Process this to update achievement level & last passed music point
	
	musicPoint* p = NULL;
	int benchmark = 0;
	
	if(mLastPassedMusicPoint >= 0)
	{
		p = (*mMusicPoints)[mLastPassedMusicPoint];
		benchmark = (*mPointBenchmarks)[p];
	}
	
	if(benchmark != 0 && mScore >= benchmark)
	{
		mAchievementLevel = ACHIEVEMENT_MAX;
	}
	else
	{
		//Find percent of benchmark
		
		if(timestamp < 5000)
		{
			mAchievementLevel = 6;
		}
		else if(p != NULL)
		{
			/*
			float percent = (float)( (float) mScore / (float) (*mPointBenchmarks)[p] );
			mAchievementLevel = (int)(percent * ( (float) ACHIEVEMENT_MAX ) );
			if(mAchievementLevel = 0)
			{
				mAchievementLevel = 1;
			}
			*/
			
			float percent = (float)( (float) mScore / (float) (*mPointBenchmarks)[p] );
			
			if(percent > 0.9)
			{
				mAchievementLevel = ACHIEVEMENT_MAX;
			}
			else if(percent > 0.8)
			{
				mAchievementLevel = ACHIEVEMENT_MAX - 1;
			}
			else if(percent > 0.7)
			{
				mAchievementLevel = ACHIEVEMENT_MAX - 2;
			}
			else if(percent > 0.6)
			{
				mAchievementLevel = ACHIEVEMENT_MAX - 3;
			}
			else if(percent > 0.5)
			{
				mAchievementLevel = ACHIEVEMENT_MAX - 4;
			}
			else if(percent > 0.4)
			{
				mAchievementLevel = ACHIEVEMENT_MAX - 5;
			}
			else if(percent > 0.3)
			{
				mAchievementLevel = ACHIEVEMENT_MAX - 6;
			}
			else if(percent > 0.2)
			{
				mAchievementLevel = ACHIEVEMENT_MAX - 7;
			}
			else if(percent > 0.1)
			{
				mAchievementLevel = ACHIEVEMENT_MAX - 8;
			}
			else
			{
				mAchievementLevel = 0;
			}
			//mAchievementLevel = (int)(percent * ( (float) ACHIEVEMENT_MAX ) );
			
		}
	}
	
	/*
	NOT NECESSARY --> assuming Mayank's Ogre code calls setLastPassedMusicPoint()
	
	//Access the last point's tatum time value
	musicPoint* lastPoint = (*mMusicPoints)[ mMusicPoints->size() - 1];
	float percentCompleted = (float)(  ((float)timestamp/1000.0f) / lastPoint->time);
	
	float seconds = (float) ( (float)timestamp / 1000.0 );
	
	for(int i = 0; i < mMusicPoints->size(); i++)
	{
		musicPoint* point = (*mMusicPoints)[i];
		if(point->time >= seconds)
		{
			if(i > 0)
			{
				mLastPassedMusicPoint = i - 1;
				return;
			}
			else
			{
				mLastPassedMusicPoint = 0;
				return;
			}
		}
	}
	
	*/
}

void Game::setMusicPoints(vector<musicPoint*>* musicPoints)
{
	mMusicPoints = musicPoints;
	
	//Now create score quotas for each point
	mPointBenchmarks = new map<musicPoint*, int>();
	
	//This is the max amount of points there are per level
	int totalScore = 25000;
	
	/*
	TODO: make this so that it attributes points based on how long
	that segment is
	*/
	int scorePerPoint = totalScore / mMusicPoints->size();
	int sum = 0;
	for(int i = 0; i < mMusicPoints->size(); i++)
	{
		musicPoint* p = (*mMusicPoints)[i];
		sum += scorePerPoint;
		(*mPointBenchmarks)[p] = sum;
	}
	
	
	/*
	map<musicPoint*, int>::const_iterator iter;
    for (iter = mPointBenchmarks->begin(); iter != mPointBenchmarks->end(); ++iter) {
        cout << iter->second << " " << iter->first << endl;
    }
    */
}

void Game::tookAudioTexturedPath()
{
	//Increase score by the appropriate difference
	
	//Determine score relativaty to last benchmark
	musicPoint* p = (*mMusicPoints)[mLastPassedMusicPoint2];
	int requiredScoreForLastPoint = (*mPointBenchmarks)[p];
	int diff = mScore - requiredScoreForLastPoint;
	
	//Determine what the new score should be, based on relativity
	
	//This should be the audio textured point we just jumped to
	musicPoint* p2 = (*mMusicPoints)[mLastPassedMusicPoint];
	
	int requiredScoreForNewPoint = (*mPointBenchmarks)[p2];
	
	//Now modify score
	mScore = requiredScoreForNewPoint + diff;
	
}

void Game::setCommands(vector<Command_t*>* commands)
{
	assert(commands);
	mCommands = commands;
}

void Game::setPlayerCharacter(PlayerCharacter* p)
{
	assert(p);
	mPlayer = p;
	mPlayer->setGame(this);
}

void Game::addEnemy(NonPlayerCharacter* e)
{
	assert(e);
	e->setGame(this);
	mEnemies->push_back(e);
}

bool Game::isOver()
{
	//
	return false;
}

const char* strlstr(const char* s1, const char* s2)
{
	//
	const char* result = strstr(s1, s2);
	if(result == NULL)
	{
		return NULL;
	}
	
	const char* last = result;
	int i = 1;
	while( (result = strstr( &(result[1]), s2) ) != NULL)
	{
		last = result;
		//i++;
	}
	
	return last;
}
